package com.lagou.java;

import com.lagou.java.handler.UserServiceHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NettyServer {

    private static ExecutorService executor =
            Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    public static void startServer (String hostName, int port){
        Channel channel = null;
        NioEventLoopGroup bossLoopGroup = null;
        NioEventLoopGroup childLoopGroup = null;
        try {
            bossLoopGroup = new NioEventLoopGroup();
            childLoopGroup = new NioEventLoopGroup();
            ServerBootstrap bootstrap = new ServerBootstrap();

            bootstrap.group(bossLoopGroup, childLoopGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
//                            pipeline.addLast(new StringDecoder());
                            // Netty半包解码器解决TCP粘包/拆包问题
                            pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 0, 2));
                            // 返回结果编码码器
                            pipeline.addLast(new StringEncoder());
                            // 入参解码器
                            pipeline.addLast(new RpcDecoder());
                            // 自定义 ChannelHandler
                            pipeline.addLast(new UserServiceHandler());
                        }
                    });
            // 绑定端口
            ChannelFuture sync = bootstrap.bind(hostName,port).sync();
            channel = sync.channel();
            if (channel != null) {
                System.out.println("========>>>>> netty server started at " + hostName + ":" + port);
            } else {
                System.out.println("========>>>>> netty server started failed ");
            }
            // 阻塞 main 线程
            ChannelFuture channelFuture = channel.closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 服务端优雅关闭
            bossLoopGroup.shutdownGracefully();
            childLoopGroup.shutdownGracefully();

        }
    }


}
